/**
 * 数据库健康检查服务
 * 提供数据库状态监控、性能分析和自动恢复功能
 */

const EventEmitter = require('events');

class DatabaseHealthService extends EventEmitter {
  constructor(dbPool, options = {}) {
    super();
    
    this.dbPool = dbPool;
    this.options = {
      checkInterval: options.checkInterval || 60000, // 1分钟
      performanceThreshold: options.performanceThreshold || 5000, // 5秒
      errorThreshold: options.errorThreshold || 10, // 10个错误
      autoRestart: options.autoRestart !== false,
      ...options
    };
    
    this.healthHistory = [];
    this.errorCount = 0;
    this.lastHealthCheck = null;
    this.isRunning = false;
    
    // 监听数据库池事件
    this.setupEventListeners();
  }

  /**
   * 设置事件监听器
   */
  setupEventListeners() {
    this.dbPool.on('queryFailed', (data) => {
      this.errorCount++;
      this.emit('queryError', data);
      
      if (this.errorCount >= this.options.errorThreshold) {
        this.emit('errorThresholdExceeded', { errorCount: this.errorCount });
      }
    });

    this.dbPool.on('transactionFailed', (data) => {
      this.emit('transactionError', data);
    });

    this.dbPool.on('poolOverflow', (status) => {
      this.emit('poolOverflow', status);
    });

    this.dbPool.on('healthCheckFailed', (error) => {
      this.emit('healthCheckFailed', error);
    });
  }

  /**
   * 启动健康检查
   */
  start() {
    if (this.isRunning) {
      console.log('数据库健康检查已在运行');
      return;
    }

    this.isRunning = true;
    this.healthCheckTimer = setInterval(() => {
      this.performHealthCheck();
    }, this.options.checkInterval);

    console.log(`数据库健康检查已启动，检查间隔: ${this.options.checkInterval}ms`);
    this.emit('healthServiceStarted');
  }

  /**
   * 停止健康检查
   */
  stop() {
    if (!this.isRunning) {
      return;
    }

    this.isRunning = false;
    if (this.healthCheckTimer) {
      clearInterval(this.healthCheckTimer);
      this.healthCheckTimer = null;
    }

    console.log('数据库健康检查已停止');
    this.emit('healthServiceStopped');
  }

  /**
   * 执行健康检查
   */
  async performHealthCheck() {
    const checkStartTime = Date.now();
    
    try {
      // 获取数据库池状态
      const poolStatus = this.dbPool.getStatus();
      const metrics = this.dbPool.getMetrics();
      
      // 执行简单查询测试
      const queryStartTime = Date.now();
      await this.dbPool.query('SELECT 1 as health_check');
      const queryTime = Date.now() - queryStartTime;
      
      // 分析健康状态
      const healthStatus = this.analyzeHealth(poolStatus, metrics, queryTime);
      
      // 记录健康检查结果
      const healthRecord = {
        timestamp: new Date(),
        status: healthStatus.status,
        poolStatus,
        metrics,
        queryTime,
        issues: healthStatus.issues,
        recommendations: healthStatus.recommendations
      };
      
      this.lastHealthCheck = healthRecord;
      this.addToHistory(healthRecord);
      
      // 发出健康检查完成事件
      this.emit('healthCheckCompleted', healthRecord);
      
      // 如果有问题，尝试自动修复
      if (healthStatus.status !== 'healthy' && this.options.autoRestart) {
        await this.attemptAutoRecovery(healthStatus);
      }
      
    } catch (error) {
      console.error('健康检查执行失败:', error);
      this.emit('healthCheckError', error);
    }
  }

  /**
   * 分析健康状态
   */
  analyzeHealth(poolStatus, metrics, queryTime) {
    const issues = [];
    const recommendations = [];
    let status = 'healthy';

    // 检查查询性能
    if (queryTime > this.options.performanceThreshold) {
      issues.push(`查询响应时间过长: ${queryTime}ms`);
      recommendations.push('考虑优化查询或增加连接池大小');
      status = 'warning';
    }

    // 检查连接池状态
    if (poolStatus.waitingQueue > 0) {
      issues.push(`有 ${poolStatus.waitingQueue} 个请求在等待连接`);
      recommendations.push('考虑增加最大连接数');
      status = 'warning';
    }

    // 检查连接池利用率
    const utilizationRate = (poolStatus.activeConnections / poolStatus.maxConnections) * 100;
    if (utilizationRate > 80) {
      issues.push(`连接池利用率过高: ${utilizationRate.toFixed(1)}%`);
      recommendations.push('考虑增加连接池大小');
      status = 'warning';
    }

    // 检查错误率
    if (metrics && metrics.totalQueries > 0) {
      const errorRate = (metrics.failedQueries / metrics.totalQueries) * 100;
      if (errorRate > 5) {
        issues.push(`查询错误率过高: ${errorRate.toFixed(1)}%`);
        recommendations.push('检查数据库连接和查询语句');
        status = 'critical';
      }
    }

    // 检查不健康的连接
    const unhealthyConnections = poolStatus.connectionAges?.filter(conn => !conn.isHealthy) || [];
    if (unhealthyConnections.length > 0) {
      issues.push(`有 ${unhealthyConnections.length} 个不健康的连接`);
      recommendations.push('重启连接池以清理不健康的连接');
      status = 'warning';
    }

    return { status, issues, recommendations };
  }

  /**
   * 尝试自动恢复
   */
  async attemptAutoRecovery(healthStatus) {
    console.log('尝试自动恢复数据库连接池...');
    
    try {
      // 如果是严重问题，重启连接池
      if (healthStatus.status === 'critical') {
        console.log('检测到严重问题，重启连接池');
        // 这里可以实现连接池重启逻辑
        this.emit('autoRecoveryAttempted', { action: 'restart', reason: 'critical_issues' });
      }
      
      // 重置错误计数
      this.errorCount = 0;
      
    } catch (error) {
      console.error('自动恢复失败:', error);
      this.emit('autoRecoveryFailed', error);
    }
  }

  /**
   * 添加到历史记录
   */
  addToHistory(record) {
    this.healthHistory.push(record);
    
    // 保持历史记录在合理范围内（最多100条）
    if (this.healthHistory.length > 100) {
      this.healthHistory.shift();
    }
  }

  /**
   * 获取健康状态报告
   */
  getHealthReport() {
    const recentHistory = this.healthHistory.slice(-10); // 最近10次检查
    const healthyCount = recentHistory.filter(r => r.status === 'healthy').length;
    const warningCount = recentHistory.filter(r => r.status === 'warning').length;
    const criticalCount = recentHistory.filter(r => r.status === 'critical').length;

    return {
      currentStatus: this.lastHealthCheck,
      recentHistory,
      summary: {
        totalChecks: recentHistory.length,
        healthyCount,
        warningCount,
        criticalCount,
        healthRate: recentHistory.length > 0 ? (healthyCount / recentHistory.length) * 100 : 0
      },
      isRunning: this.isRunning,
      errorCount: this.errorCount
    };
  }

  /**
   * 重置统计信息
   */
  reset() {
    this.healthHistory = [];
    this.errorCount = 0;
    this.lastHealthCheck = null;
    console.log('数据库健康检查统计信息已重置');
  }
}

module.exports = DatabaseHealthService;
